package com.i2works.smartluolong.utils.common;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.google.common.collect.Lists;
import com.i2works.smartluolong.utils.base.AppConstant;
import com.i2works.smartluolong.utils.base.MsgEnum;
import com.i2works.smartluolong.utils.entity.R;
import com.i2works.smartluolong.utils.entity.Result;
import com.i2works.smartluolong.utils.redis.RedisSessionDAO;
import com.xiaoleilu.hutool.util.CollectionUtil;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;

/**
 * 短信验证码
 *
 * @author Liu Yutao <koal@vip.qq.com>
 * @date 2018/01/15 14:28
 */
@Component
public class SmsUtil {

    protected final static Logger logger = LoggerFactory.getLogger(SmsUtil.class);

    //短信API产品名称
    private final static String PRODUCT = "Dysmsapi";
    //短信API产品域名
    private final static String DOMAIN = "dysmsapi.aliyuncs.com";
    //区域编号
    private final static String REGION_ID = "cn-hangzhou";

    @Autowired
    private RedisSessionDAO redisSessionDAO;


//
//    /**
//     * 请求发送通知消息
//     *
//     * @param templateCode 模板代码
//     * @param itemTitle    模板占位符（事项名称）
//     * @param phoneNumbers 手机号码
//     * @return result
//     */
//    public Result testNotify(String templateCode, String itemTitle, List<String> phoneNumbers) {
//        if (CollectionUtil.isEmpty(phoneNumbers)) {
//            return R.error(MsgEnum.ACCESS_PHONE_NULL.getMsg());
//        }
//        if (StringUtils.isAnyBlank(templateCode)) {
//            return R.error(MsgEnum.SMS_INFORM_PARAMS_ERROR.getMsg());
//        }
//        try {
//            //设置超时时间-可自行调整
//            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
//            System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//            //初始化ascClient,暂时不支持多region（请勿修改）
//            IClientProfile profile = DefaultProfile.getProfile(REGION_ID, AppConstant.ALIYUN_SMS_KEYID, AppConstant.ALIYUN_SMS_KEYSECRET);
//            DefaultProfile.addEndpoint(REGION_ID, REGION_ID, PRODUCT, DOMAIN);
//            IAcsClient acsClient = new DefaultAcsClient(profile);
//            //组装请求对象
//            SendSmsRequest request = new SendSmsRequest();
//            //使用post提交
//            request.setMethod(MethodType.POST);
//            //必填:待发送手机号
//            request.setPhoneNumbers(formatPhoneList(phoneNumbers));
//            //必填:短信签名
//            request.setSignName(AppConstant.ALIYUN_SMS_SIGNNAME);
//            //必填:短信模板
//            request.setTemplateCode(templateCode);
//            JSONObject templateParam = new JSONObject();
//            templateParam.put("number","51888");
//            templateParam.put("waiting","88888");
//            request.setTemplateParam(templateParam.toJSONString());
//            //请求失败这里会抛ClientException异常
//            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
//            if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//                //返回消息
//                return R.success(MsgEnum.SMS_INFORM_SEND_SUCCESS.getMsg());
//            } else {
//                logger.error(sendSmsResponse.getMessage());
//                return R.error(MsgEnum.SMS_INFORM_SEND_ERROR.getMsg());
//            }
//        } catch (ClientException e) {
//            e.printStackTrace();
//            logger.error("短信发送异常：" + e.getMessage());
//            return R.error(MsgEnum.SMS_INFORM_SEND_ERROR.getMsg());
//        }
//    }



    /**
     * 请求发送通知消息
     *
     * @param templateCode 模板代码
     * @param itemTitle    模板占位符（事项名称）
     * @param phoneNumbers 手机号码
     * @return result
     */

    public Result notify(String templateCode, String itemTitle, List<String> phoneNumbers) {
        if (CollectionUtil.isEmpty(phoneNumbers)) {
            return R.error(MsgEnum.ACCESS_PHONE_NULL.getMsg());
        }
        if (StringUtils.isAnyBlank(templateCode)) {
            return R.error(MsgEnum.SMS_INFORM_PARAMS_ERROR.getMsg());
        }
        try {
            //设置超时时间-可自行调整
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");
            //初始化ascClient,暂时不支持多region（请勿修改）
            IClientProfile profile = DefaultProfile.getProfile(REGION_ID, AppConstant.ALIYUN_SMS_KEYID, AppConstant.ALIYUN_SMS_KEYSECRET);
            DefaultProfile.addEndpoint(REGION_ID, REGION_ID, PRODUCT, DOMAIN);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            //组装请求对象
            SendSmsRequest request = new SendSmsRequest();
            //使用post提交
            request.setMethod(MethodType.POST);
            //必填:待发送手机号
            request.setPhoneNumbers(formatPhoneList(phoneNumbers));
            //必填:短信签名
            request.setSignName(AppConstant.ALIYUN_SMS_SIGNNAME);
            //必填:短信模板
            request.setTemplateCode(templateCode);
            JSONObject templateParam = new JSONObject();
            templateParam.put("itemTitle",itemTitle);
            request.setTemplateParam(templateParam.toJSONString());
            //请求失败这里会抛ClientException异常
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
            if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
                //返回消息
                return R.success(MsgEnum.SMS_INFORM_SEND_SUCCESS.getMsg());
            } else {
                logger.error(sendSmsResponse.getMessage());
                return R.error(MsgEnum.SMS_INFORM_SEND_ERROR.getMsg());
            }
        } catch (ClientException e) {
            e.printStackTrace();
            logger.error("短信发送异常：" + e.getMessage());
            return R.error(MsgEnum.SMS_INFORM_SEND_ERROR.getMsg());
        }
    }


    /**
     * 发送验证码到阿里云服务器， 请求发送验证码
     *
     * @param templateCode 模板代码
     * @param phoneNumbers 手机号码
     * @return result
     */
    public Result captcha(String templateCode, List<String> phoneNumbers) {

        if (StringUtils.isAnyBlank(templateCode)) {
            return R.error(MsgEnum.SMS_CODE_PARAMS_ERROR.getMsg());
        }
        try {
            //设置超时时间-可自行调整
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");
            //初始化ascClient,暂时不支持多region（请勿修改）
            IClientProfile profile = DefaultProfile.getProfile(REGION_ID, AppConstant.ALIYUN_SMS_KEYID, AppConstant.ALIYUN_SMS_KEYSECRET);
            DefaultProfile.addEndpoint(REGION_ID, REGION_ID, PRODUCT, DOMAIN);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            //组装请求对象
            SendSmsRequest request = new SendSmsRequest();
            //使用post提交
            request.setMethod(MethodType.POST);
            //必填:待发送手机号
            request.setPhoneNumbers(formatPhoneList(phoneNumbers));
            //必填:短信签名
            request.setSignName(AppConstant.ALIYUN_SMS_SIGNNAME);
            //必填:短信模板
            request.setTemplateCode(templateCode);
            String code = String.valueOf(RandomUtils.nextInt(100000, 999999));
            //模板变量；如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为其替换值
            JSONObject templateParam = new JSONObject();
            templateParam.put("code", code);
            request.setTemplateParam(templateParam.toJSONString());
            //请求失败这里会抛ClientException异常
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
            if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
                //把短信验证码存储到redis里边，过期时间5分钟(单位是秒)
                redisSessionDAO.set(phoneNumbers.get(0), code, 300L);
                //返回消息
                return R.success(MsgEnum.SMS_CODE_SEND_SUCCESS.getMsg());
            } else {
                logger.error(sendSmsResponse.getMessage());
                return R.error(MsgEnum.SMS_CODE_SEND_ERROR.getMsg());
            }
        } catch (ClientException e) {
            logger.error("短信发送异常：" + e.getMessage());
            return R.error(MsgEnum.SMS_CODE_SEND_ERROR.getMsg());
        }
    }


    /**
     * 对比验证码
     */
    public Result contrast(String phone, String code) {
        //非空校验
        if (StringUtils.isBlank(phone)) {
            return R.error(MsgEnum.ACCESS_PHONE_NULL.getMsg());
        }
        if (StringUtils.isBlank(code)) {
            return R.error(MsgEnum.SMS_CODE_EMPTY.getMsg());
        }
        //从redis中获取验证码
        boolean exists = redisSessionDAO.exists(phone);
        //获取失败说明验证码已过期
        if (!exists) {
            return R.error(MsgEnum.SMS_CODE_TIMEOUT.getMsg());
        }
        String cacheCode = String.valueOf(redisSessionDAO.get(phone));
        //对比
        if (cacheCode.equalsIgnoreCase(code)) {
            redisSessionDAO.remove(phone);
            return R.success();
        } else {
            return R.error(MsgEnum.SMS_CODE_ERROR.getMsg());
        }
    }

    /**
     * 对比验证码
     */
    public Result delete(String phone) {
        //从redis中获取验证码
        boolean exists = redisSessionDAO.exists(phone);
        //如果存在就删除
        if (exists) {
            redisSessionDAO.remove(phone);
        }
        return R.success();
    }


    /**
     * 手机号码过滤重复
     */
    private String formatPhoneList(List<String> sources) {
        List<String> result = Lists.newArrayList();
        for (String phone : sources) {
            if (Collections.frequency(result, phone) < 1) {
                result.add(phone);
            }
        }
        return CollectionUtil.join(result, ",");
    }


}
